require "pathname"
require "cgi"

# load the openid library
begin
  require "rubygems"
  require_gem "ruby-openid", ">= 1.0.2"
rescue LoadError
  require "openid"
end

class AuthController < ApplicationController
  layout  'scaffold'
  
  # process the login request, disover the openid server, and
  # then redirect.
  def login
    openid_url = @params[:openid_url]

    if @request.post?
      if openid_url.blank?
        self.current_user = User.authenticate(params[:login], params[:password])
        if logged_in?
          if params[:remember_me] == "1"
            self.current_user.remember_me
            cookies[:auth_token] = { :value => 
                self.current_user.remember_token , :expires => 
                self.current_user.remember_token_expires_at }
          end
          redirect_back_or_default(:controller => 'user', :action=>'view',:id=> "#{current_user.login}")
        else
          flash[:notice] = "Logged in unsuccessfully"
          redirect_back_or_default(:controller => '/account', :action => 'login')
        end
      else
        request = consumer.begin(openid_url)

        case request.status
        when OpenID::SUCCESS
          return_to = url_for(:action=> 'complete')
          trust_root = url_for(:controller=>'')

          url = request.redirect_url(trust_root, return_to)
          redirect_to(url)
          return

        when OpenID::FAILURE
          escaped_url = CGI::escape(openid_url)
          flash[:notice] = "Could not find OpenID server for #{escaped_url}"

        else
          flash[:notice] = "An unknown error occured."
        end      
      end

    end    

  end

  # handle the openid server response
  def complete
    response = consumer.complete(@params)
    
    case response.status
    when OpenID::SUCCESS
      #设置 session
      @current_user = User.find_by_openid_url(response.identity_url[0..(response.identity_url.size-2)])
      if @current_user
        current_user = @current_user
        session[:user] = @current_user.id
        redirect_to("/user/view/#{@current_user.login}")
      else
        flash[:notice] = "<br>你的openid: #{response.identity_url} 没有绑定,'app_title'.t 帐号.<br>请用'app_title'.t 方法登陆，绑定后可以用openid登陆"
        redirect_to("/account/login")
      end 
      return

    when OpenID::FAILURE
      if response.identity_url
        flash[:notice] = "Verification of #{CGI::escape(response.identity_url)} failed."

      else
        flash[:notice] = 'Verification failed.'
      end

    when OpenID::CANCEL
      flash[:notice] = 'Verification cancelled.'

    else
      flash[:notice] = 'Unknown response from OpenID server.'
    end
  
    redirect_to :action => 'login'
  end
  #绑定openid
  def openid
    openid_url = @params[:openid_url]
    
    request = consumer.begin(openid_url)
    error_text = <<-eol
        <font color='red'>绑定openid失败：请重新绑定</font>
        <form action="/auth/openid" method="post" onsubmit="new Ajax.Updater('openid', '/auth/openid', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
            <input type="text" id="openid_url" name="openid_url">
             <input type="submit" name='submit' value="提交">
        </form>
    eol
    case request.status
                          
    when OpenID::SUCCESS

      o = params[:openid_url]
      u = User.find_by_id(session[:user])
      u.openid_url = o
      if u.save
        render :text=>"<font color='green'>绑定openid:#{o}<br>成功</font>"
      else
        render :text=>"#{error_text}"
      end

    when OpenID::FAILURE
      render :text=>"#{error_text}"

    else
      render :text=>"#{error_text}"
    end      
    
    

  end
  def logout
    @session[:user_id] = nil
  end
    
  def welcome
  end

  private

  # Get the OpenID::Consumer object.
  def consumer
    # create the OpenID store for storing associations and nonces,
    # putting it in your app's db directory
    store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
    store = OpenID::FilesystemStore.new(store_dir)

    return OpenID::Consumer.new(@session, store)
  end

  # get the logged in user object
  def find_user
    return nil if session[:user_id].nil?
    User.find(session[:user_id])
  end
  
end
